#include "..\wow6mapper\wow6mapper\ChunkHeader.h"
#include "wdt.h"
#include "log.h"

extern Log * pLog;

//------------------------------------------------------------------------------
Wdt::Wdt( const BufferS_t &buffer ) {
  if ( buffer.size() <= 0 ) {
    quitApp( "[WDT] buffer invalid" );
    return;
  }

  // create an istream of our buffer
  std::stringbuf str_buf( buffer );
  std::istream i_str( &str_buf );


  std::streamoff chunk_start = i_str.tellg();
  std::streamoff cur_pos = chunk_start;
  ChunkHeader_s header;

  uint32_t size = buffer.size();

  while (cur_pos < size)
  {
	  i_str.read((char *)&header, sizeof(ChunkHeader_s));
	  i_str.seekg(cur_pos, std::ios::beg);									  // need to rewind the stream 

	  if (checkChunkId((char *)&header, "MVER"))
	  {
		  i_str.read((char*)&_mverChunk, sizeof(MverChunk_s));
	  }
	  else if (checkChunkId((char *)&header, "MPHD"))
	  {
		  i_str.read((char*)&_mphdChunk, sizeof(MphdChunk_s));
	  }
	  else if (checkChunkId((char *)&header, "MAIN"))
	  {
		  i_str.read((char*)&_mainChunk, sizeof(MainChunk_s));

		  // I could just say 64*64, but it's there to check that everything went right
		  size_t count = _mainChunk.size / sizeof(MainChunk_s::AsyncObject_s);
		  size_t num_adts = 0;
		  _asyncObjects.resize(count);

		  // read flags from buffer
		  for (size_t i = 0; i < count; i++) {
			  i_str.read((char*)&_asyncObjects[i], sizeof(MainChunk_s::AsyncObject_s));

			  if (_asyncObjects[i].flags & 0x1) {
				  num_adts++;
			  }
		  }

		  _adtCoords.resize(num_adts);
		  int i = 0;
		  for (int y = 0; y < 64; y++) {
			  for (int x = 0; x < 64; x++) {
				  // get all tiles with flag & 1
				  if (_asyncObjects[y * 64 + x].flags & 0x1) {
					  _adtCoords[i].x = x;
					  _adtCoords[i].y = y;
					  i++;
				  }
			  }
		  }
	  }
	
	  else
	  {
		  // should never get here
		  pLog->Write("WDT unknow chunk %s", header.id);
		  i_str.seekg(cur_pos + 0x8 + header.size, std::ios::beg);
	  }
	  cur_pos = i_str.tellg();
  }
}

//------------------------------------------------------------------------------
const AdtCoords_t& Wdt::getAdtCoords() const {
  return _adtCoords;
}